package com.train.batch.service.impl;

import com.train.batch.resp.JobPageResp;
import com.train.batch.dto.AddJobDTO;
import com.train.batch.dto.JobPageDTO;
import com.train.batch.service.BatchService;
import com.train.batch.service.QrtzJobRecordService;
import com.train.common.enums.impl.BizExceptionEnums;
import com.train.common.exception.GlobalException;
import com.train.common.resp.PageResp;
import com.train.quartz.executor.JobExecutor;
import jakarta.annotation.Resource;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
public class BatchServiceImpl implements BatchService {

    @Autowired
    private JobExecutor jobExecutor;

    @Resource
    private QrtzJobRecordService qrtzJobRecordService;

    @Transactional
    @Override
    public void addJob(AddJobDTO addJobDTO) {
        try {
            //检查任务是否存在
            if (jobExecutor.exists(addJobDTO.getJobName(), addJobDTO.getGroupName())) {
                throw new GlobalException(BizExceptionEnums.EXP_EXISTS_JOB);
            }

            //执行
            jobExecutor.addJob(addJobDTO.getJobName(),
                    addJobDTO.getGroupName(),
                    addJobDTO.getJobParam(),
                    addJobDTO.getCronExpress(),
                    addJobDTO.getRetryCount(),
                    addJobDTO.getRetryInterval());

            qrtzJobRecordService.saveJob(addJobDTO.getJobName(), addJobDTO.getGroupName(), addJobDTO.getCronExpress());
        } catch (SchedulerException e) {
            throw new GlobalException(BizExceptionEnums.EXP_ADD_JOB);
        }
    }

    @Transactional
    @Override
    public void deleteJob(String jobName, String groupName) {
        try {
            //检查任务是否存在
            validation(jobName, groupName);

            //执行
            jobExecutor.deleteJob(jobName, groupName);

            qrtzJobRecordService.deleteJob(jobName, groupName);
        } catch (SchedulerException e) {
            throw new GlobalException(BizExceptionEnums.EXP_DELETE_JOB);
        }
    }

    @Transactional
    @Override
    public void pauseJob(String jobName, String groupName) {
        try {
            //检查任务是否存在
            validation(jobName, groupName);

            //执行
            jobExecutor.pauseJob(jobName, groupName);

            qrtzJobRecordService.editJobStatus(jobName, groupName);
        } catch (SchedulerException e) {
            throw new GlobalException(BizExceptionEnums.EXP_PAUSE_JOB);
        }
    }

    @Transactional
    @Override
    public void resumeJob(String jobName, String groupName) {
        try {
            //检查任务是否存在
            validation(jobName, groupName);

            //执行
            jobExecutor.resumeJob(jobName, groupName);

            qrtzJobRecordService.editJobStatus(jobName, groupName);
        } catch (SchedulerException e) {
            throw new GlobalException(BizExceptionEnums.EXP_RESUME_JOB);
        }
    }

    @Override
    public void runJob(String jobName, String groupName) {
        try {
            //检查任务是否存在
            validation(jobName, groupName);

            //执行
            jobExecutor.executeJob(jobName, groupName);
        } catch (SchedulerException e) {
            throw new GlobalException(BizExceptionEnums.EXP_RUN_JOB);
        }
    }

    @Transactional
    @Override
    public void updateJob(String jobName, String groupName, String cronExpress) {
        try {
            //检测任务是否存在
            validation(jobName, groupName);

            //更新
            Date nextTime = jobExecutor.updateJob(jobName, groupName, cronExpress);

            qrtzJobRecordService.editJob(jobName, groupName, cronExpress, nextTime);
        } catch (SchedulerException e) {
            throw new GlobalException(BizExceptionEnums.EXP_UPDATE_JOB);
        }
    }

    @Override
    public PageResp<JobPageResp> pageList(JobPageDTO pageDTO) {
        return qrtzJobRecordService.pageList(pageDTO);
    }

    private void validation(String jobName, String groupName) throws SchedulerException {
        boolean exists = jobExecutor.exists(jobName, groupName);
        if (!exists) {
            throw new GlobalException(BizExceptionEnums.EXP_NOT_EXISTS_JOB);
        }
    }
}
